import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Logger } from 'winston';
import { Inject } from '@nestjs/common/decorators';
import { Request, Response } from 'express';

@Injectable()
export class LoggerInterceptor implements NestInterceptor {
  constructor(@Inject('winston') private readonly logger: Logger) {}

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const request: Request = context.switchToHttp().getRequest();
    const { method, url, ip, headers } = request;

    const now = Date.now();

    return next.handle().pipe(
      tap(() => {
        const response: Response = context.switchToHttp().getResponse();
        const { statusCode } = response;
        const contentLength = response.get('content-length') || 0;

        this.logger.info('HTTP Request', {
          type: 'HTTP',
          method,
          url,
          statusCode,
          contentLength,
          ip,
          userAgent: headers['user-agent'],
          duration: `${Date.now() - now}ms`,
          requestId: request['requestId'] as string,
        });
      }),
    );
  }
}
